<script lang="ts" setup>
import { ref } from 'vue';
import { Send as SendIcon } from 'lucide-vue-next';
import { toTypedSchema } from '@vee-validate/zod';
import * as z from 'zod';
import type { GenericObject } from 'vee-validate';
import type { FetchResponse } from 'ofetch';
import { useToast } from '~/components/ui/toast';
import { userApi, type UserLogin } from '~/utils/api/user-api';
import type { Result } from '~/utils/api/type';

definePageMeta({
	layout: 'none',
});

const router = useRouter();
const { toast } = useToast();
// PinInput value
const value = ref<string[]>([]);
const step = ref(0);
const countdown = ref(60);
let intervalId: NodeJS.Timeout | undefined = undefined;

const form = ref({
	email: '',
	password: '',
});

// 表单验证
const formSchema = toTypedSchema(z.object({
	email: z.string({ required_error: '邮箱不能为空' }).email({ message: '请输入有效的邮箱地址' }),
	password: z.string({ required_error: '密码不能为空' }).min(6, { message: '密码至少6位' }),
	confirmPassword: z.string({ required_error: '密码不能为空' }).min(6, { message: '密码至少6位' }),
}).refine(data => data.password === data.confirmPassword, {
	message: '密码和确认密码不一致',
	path: ['confirmPassword'],
}));

let hasBackBeenCalled = false;

// 返回
function back() {
	switch (step.value) {
		case 0:
			if (!hasBackBeenCalled) {
				router.back();
				hasBackBeenCalled = true;
			}
			break;
		case 1:
			step.value = 0;
	}
}

// 转到验证码页面
const toCodePage = async (value: GenericObject) => {
	form.value.email = value.email;
	form.value.password = value.password;
	step.value = 1;

	const result = await userApi.sendCaptcha(form.value.email);
	if (result.code !== 200) {
		toast({ description: '发送验证码失败' });
		step.value = 0;
	}
	else {
		countdown.value = 60;
		startCountdown();
	}
};

// 开始倒计时
const startCountdown = () => {
	intervalId = setInterval(() => {
		if (countdown.value > 0) {
			countdown.value--;
		}
		else {
			clearInterval(intervalId);
		}
	}, 1000);
};

// 验证码输入完成触发
const handleComplete = (e: string[]) => {
	// 验证码输入完成，提交注册
	userApi.userRegister({
		email: form.value.email,
		password: form.value.password,
		captcha: e.join(''),
	}).then((res) => {
		if (res.code === 200) {
			toast({ description: '注册成功' });
			router.push('/login');
		}
	}).catch((err: FetchResponse<Result<UserLogin>>) => {
		toast({ description: typeof err._data?.message == 'string' ? err._data?.message : err._data?.message[0] });
	});
};

// 重新发送验证码
const resend = async () => {
	const result = await userApi.sendCaptcha(form.value.email);
	if (result.code === 200) {
		countdown.value = 60;
		startCountdown();
	}
	else {
		toast({ description: '发送验证码失败' });
	}
};

onUnmounted(() => {
	clearInterval(intervalId);
});
</script>

<template>
	<div>
		<FloatBack @click="back" />
		<Transition
			name="blur"
		>
			<!-- 注册 -->
			<div
				v-if="step==0"
				class="w-full h-[100vh] lg:grid lg:grid-cols-2"
			>
				<div class="h-full flex items-center justify-center py-12">
					<div class="mx-auto grid w-[350px] gap-6">
						<div class="grid gap-5 text-center">
							<h1 class="text-3xl font-bold">
								注册
							</h1>
							<p class="text-balance text-muted-foreground">
								输入您的信息以创建帐户
							</p>
						</div>
						<Form
							:validation-schema="formSchema"
							class="grid gap-5"
							@submit="toCodePage"
						>
							<!-- 邮箱 -->
							<FormField
								v-slot="{ componentField }"
								name="email"
							>
								<FormItem>
									<FormLabel>邮箱</FormLabel>
									<FormControl>
										<Input
											placeholder="my@example.com"
											type="email"
											v-bind="componentField"
										/>
									</FormControl>
									<FormMessage />
								</FormItem>
							</FormField>
							<!-- 密码 -->
							<FormField
								v-slot="{ componentField }"
								name="password"
							>
								<FormItem>
									<FormLabel>密码</FormLabel>
									<FormControl>
										<Input
											type="password"
											v-bind="componentField"
										/>
									</FormControl>
									<FormMessage />
								</FormItem>
							</FormField>
							<!-- 确认密码 -->
							<FormField
								v-slot="{ componentField }"
								name="confirmPassword"
							>
								<FormItem>
									<FormLabel>确认密码</FormLabel>
									<FormControl>
										<Input
											type="password"
											v-bind="componentField"
										/>
									</FormControl>
									<FormMessage />
								</FormItem>
							</FormField>
							<Button
								class="w-full"
								type="submit"
							>
								<SendIcon class="w-4 h-4 mr-2" />
								立即注册
							</Button>
						</Form>
						<div class=" text-center text-sm">
							已有帐户？
							<a
								class="underline"
								href="/login"
							>
								立即登录
							</a>
						</div>
					</div>
				</div>
				<div class="hidden bg-muted lg:block lg:h-full">
					<img
						alt="Image"
						class="h-[100vh] w-full object-cover dark:brightness-[0.2] dark:grayscale"
						src="@/assets/image/cover.jpg"
					>
				</div>
			</div>
			<!-- 验证 -->
			<div
				v-else
				class="w-full h-[100vh]"
			>
				<div class="h-full flex items-center justify-center py-12">
					<div class="mx-auto grid w-[500px] gap-6">
						<div class="grid gap-1 text-center">
							<h1 class="text-3xl font-bold">
								请输入验证码
							</h1>
							<div class="text-balance text-muted-foreground">
								<span>已将验证码发送到</span>
								<span class="font-semibold">{{ form.email }}</span>
							</div>
						</div>
						<div class="grid gap-6 text-center">
							<div class="flex flex-col items-center">
								<PinInput
									id="pin-input"
									v-model="value"
									placeholder=""
									@complete="handleComplete"
								>
									<PinInputGroup class="gap-2">
										<template
											v-for="(id, index) in 6"
											:key="id"
										>
											<PinInputInput
												:index="index"
												class="rounded-md border-2"
											/>
										</template>
									</PinInputGroup>
								</PinInput>
							</div>
							<p class="text-sm text-muted-foreground ">
								<a
									href="#"
									@click.prevent="resend"
								>
									<span v-if="countdown === 0">重新发送</span>
									<span v-else>重新发送({{ countdown }}s)</span>
								</a>
							</p>
						</div>
					</div>
				</div>
			</div>
		</Transition>
	</div>
</template>

<style lang="postcss" scoped>

</style>
